package edu.ruc.cluster.ui;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.text.View;
import javax.swing.plaf.basic.BasicHTML;

import edu.ruc.cluster.util.Const;
import edu.ruc.cluster.util.DefaultLogHandler;
import edu.ruc.cluster.util.ColumnLayout;
import edu.ruc.cluster.util.RunCommand;
import edu.ruc.cluster.util.TestUser;
import edu.ruc.cluster.util.ImageLabel;

@SuppressWarnings("serial")
public class UserPane extends JPanel {
	
	private DefaultLogHandler logHandler = null;
	private int height = 0;
	
	private JPanel upper = null;
	private JPanel auth = null;
	private JLabel caption = null;
	private JLabel tbhost = null;
	private JLabel tbip = null;
	private JLabel tbauthuser = null;
	private JLabel tbauthpw = null;
	
	private JPanel checkauth = null;
	private JPanel checkPane = null;
	private JPanel whitespace = null;
	
	private List<String> flags = null;
	private ProgressPane pp = null;
	private JButton check = null;
	
	private List<JTextField> users = null;
	private List<JPasswordField> pws = null;	
	private List<String> ips = null;
	private List<String> names = null;
	
	private ImageIcon right = null;
	private ImageIcon wrong = null;
	boolean connected = false;
	
	
	private void getip(){
		try{
			BufferedReader reader = new BufferedReader(new FileReader(new File(Const.IP_LIST_FILE)));
			String line = null;
			while((line = reader.readLine()) != null){
				names.add(line.split(Const.LINE_SEPERATOR)[1]);
				ips.add(line.split(Const.LINE_SEPERATOR)[0]);
			}
		}catch(FileNotFoundException e){
			logHandler.error(this.getName(), e);
		}catch(IOException e){
			logHandler.error(this.getName(), e);
		}
	}
	private void addAuthPane(){
		
		right = new ImageIcon(getClass().getResource(Const.RIGHT_ICON_PATH), "right icon");
		wrong = new ImageIcon(getClass().getResource(Const.WRONG_ICON_PATH), "wrong icon");
	   
		tbhost = new JLabel("HostName");
		tbip = new JLabel("IP");
		tbauthuser = new JLabel("User");
		tbauthpw = new JLabel("Password");
		// Verdana
		tbhost.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		tbip.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		tbauthuser.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		tbauthpw.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		
		caption = new JLabel("<html>please input the user which is the sudoer " +
				"for corresponding machines together with its password</html>");
		caption.setFont(new Font("SansSerif.bold", Font.ITALIC, 16));
		caption.setForeground(Color.RED);
		// automatically line break for caption text
		int maxWidth = 500;		 
		View v = BasicHTML.createHTMLView(caption, caption.getText());		 
		v.setSize(maxWidth, Integer.MAX_VALUE);
		height = (int) v.getMinimumSpan(View.Y_AXIS); 
		caption.setPreferredSize(new Dimension(maxWidth, height));

		JPanel tmp = new JPanel();
		tmp.setLayout(new GridLayout(ips.size()+1,4, 20, 5));
		tmp.add(tbhost);
		tmp.add(tbip);
		tmp.add(tbauthuser);
		tmp.add(tbauthpw);
		Iterator<String> ipiter = ips.iterator();
		Iterator<String> nameiter = names.iterator();
		while(ipiter.hasNext()){
			tmp.add(new JLabel(nameiter.next()));
			tmp.add(new JLabel(ipiter.next()));
			JTextField username = new JTextField();
			JPasswordField password = new JPasswordField();
			users.add(username);
			pws.add(password);
			tmp.add(username);
			tmp.add(password);			
		}
		auth.add(caption);
		auth.add(tmp);
	}
	/**
	 * this panel is constructed like below:
	 *      -----------upper-part--------------
	 *      -  AuthenticatePanel  CheckPanel  -
	 *      -----------------------------------
	 *      -----------lower-part--------------
	 *      -           TextArea              -
	 *      -         ProgressPane            -
	 *      -----------------------------------
	 */
	public UserPane(){
//		constructPane();
	}
	public void constructPane(){
		
		logHandler = DefaultLogHandler.getInstance();
		ips = new ArrayList<String>();
		names = new ArrayList<String>();
		getip();
		
		auth = new JPanel(new ColumnLayout());
		auth.setBorder(new TitledBorder("cluster Authenticate"));
		users = new ArrayList<JTextField>();
		pws = new ArrayList<JPasswordField>();
		addAuthPane();
				
		checkPane = new JPanel(new ColumnLayout());
		checkPane.setBorder(new TitledBorder(" "));
		checkauth = new JPanel(new GridLayout(ips.size()+1,1, 20, 5));		
		flags = new ArrayList<String>();
		whitespace = new JPanel();
		whitespace.setPreferredSize(new Dimension(1, height));		
		checkPane.add(whitespace);
		checkPane.add(checkauth);
		
		upper = new JPanel();
		upper.setLayout(new BoxLayout(upper, BoxLayout.X_AXIS));
		upper.add(auth);
		upper.add(checkPane);
		upper.setPreferredSize(new Dimension(700, 200));
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.add(upper);		
		
			
		check = new JButton("check");
		check.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
//				Iterator<JTextField> iter = users.iterator();
//				while(iter.hasNext()){
//					System.out.println(iter.next().getText());
//				}
				checkInput();
				if(connected == false)
					JOptionPane.showMessageDialog(null, "please check the input!", "reminder", JOptionPane.ERROR_MESSAGE);
				else{
					String text = getPingResult();
//					System.out.println(text);
					if(text != null){
						pp = new ProgressPane(text);
						pp.setVisible(true);
						add(pp);
					}
				}
			}
		});
		this.add(check);
	}
	public boolean ok(){
		return connected;
	}
	/**
	 * return the ping result
	 * @return
	 */
	private String getPingResult(){
		if(connected == false)
			return null;
//		System.out.println(users.get(0).getText().trim()+"@"+ips.get(0));
		RunCommand rc = new RunCommand(users.get(0).getText().trim()+"@"+ips.get(0), 
				String.valueOf(pws.get(0).getPassword()));
		
		String[] cmd = new String[ips.size()];
		Iterator<String> ipiter = ips.iterator();
		int i = 0;
		while(ipiter.hasNext()){
			cmd[i] = "ping -c 1 " + ipiter.next().trim();
			System.out.println(cmd[i]);
			i ++;
		}
		String result = rc.runCmd(cmd);		
		rc.close();
		return result;
	}
	
	private void addCheck(String flag){
		flags.add(flag);
	}
	/**
	 * Check the literal format for the input(currently just check whether is empty or not)
	 * Check whether the user name and password can be used to ssh to a machine
	 * @return true/false
	 * 2012.11.27
	 */
	private boolean checkInput(){
		
		boolean[] isConn = new boolean[ips.size()];
		for(int i = 0 ; i < ips.size() ; i ++)
			isConn[i] = false;
		
		Iterator<String> ipiter = ips.iterator();
		Iterator<JTextField> useriter = users.iterator();
		Iterator<JPasswordField> pwiter = pws.iterator();
				
		int i = 0;
		while(useriter.hasNext()){
			String username = useriter.next().getText().toString();
			String password = String.valueOf(pwiter.next().getPassword());
			if(username.equals("") || password.equals("")){
				addCheck("Empty");
				isConn[i++] = false;
				continue;
			}
			TestUser tu = new TestUser(username+"@"+ipiter.next(), password);
			if(tu.isConnect()){
//				System.out.println("is connected aaa");
				addCheck("OK");
				isConn[i++] = true;
			}else{
				isConn[i++] = false;
				addCheck("unconnected");
			}
			
		}
		Iterator<String> iter = flags.iterator();
		JLabel tmp = new JLabel(" ");
		tmp.setFont(new Font("Consolas", Font.PLAIN, 14));
		checkauth.add(tmp);
		while(iter.hasNext()){
			String tag = iter.next();
			JLabel label = null;
			if(tag.contains("OK"))
				label = new ImageLabel(right);
			else
				label = new ImageLabel(wrong);
			checkauth.add(label);
		}
		this.updateUI();
		connected = true;
		for(i = 0 ; i < ips.size(); i ++){
			connected &= (isConn[i] == true) ? true : false;
		}
		return connected;
	}
	
	public void store(){
		Iterator<JTextField> useriter = users.iterator();
		Iterator<JPasswordField> pwiter = pws.iterator();
		Iterator<String> nameiter = names.iterator();
		try{
			FileWriter writor = new FileWriter(new File(Const.USER_PW_FILE));
			while(useriter.hasNext()){
				writor.write(nameiter.next() + Const.LINE_SEPERATOR + useriter.next().getText().trim() + Const.LINE_SEPERATOR 
						+ String.valueOf(pwiter.next().getPassword()) + "\n");
			}		
			writor.close();
		}catch(IOException e){
			logHandler.error(this.getName(), e);
		}
		
	}
	
}
